/*
 * Powered By cuichen
 * Since 2014 - 2015
 */
package com.seeyoui.kensite.framework.system.controller;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;

import org.apache.poi.ss.usermodel.Row;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.seeyoui.kensite.common.base.controller.BaseController;
import com.seeyoui.kensite.common.constants.StringConstant;
import com.seeyoui.kensite.common.base.domain.EasyUIDataGrid;
import com.seeyoui.kensite.common.base.domain.TreeJson;
import com.seeyoui.kensite.common.util.RequestResponseUtil;
import com.seeyoui.kensite.common.util.StringUtils;
import com.seeyoui.kensite.common.util.excel.ExcelUtil;
import com.seeyoui.kensite.framework.system.domain.SysDepartment;
import com.seeyoui.kensite.framework.system.service.SysDepartmentService;

/**
 * @author cuichen
 * @version 1.0
 * @since 1.0
 */
@Controller
@RequestMapping(value = "sysDepartment")
public class SysDepartmentController extends BaseController {

    @Autowired
    private SysDepartmentService sysDepartmentService;

    /**
     * 展示列表页面
     * 
     * @param modelMap
     * @param module
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysDepartment:view")
    @RequestMapping(value = "/{page}")
    public ModelAndView showSysDepartmentPageList(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap,
            @PathVariable String page) throws Exception {
        return new ModelAndView("framework/system/department/" + page, modelMap);
    }

    /**
     * 获取列表展示数据
     * 
     * @param modelMap
     * @param sysDepartment
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysDepartment:select")
    @RequestMapping(value = "/list/data", method = RequestMethod.POST)
    @ResponseBody
    public Object findList(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap,
            SysDepartment sysDepartment) throws Exception {
        List<SysDepartment> sysDepartmentList = sysDepartmentService.findList(sysDepartment);
        Integer total = sysDepartmentService.findTotal(sysDepartment);
        EasyUIDataGrid eudg = new EasyUIDataGrid();
        eudg.setRows(sysDepartmentList);
        eudg.setTotal(String.valueOf(total));
        return eudg;
    }

    /**
     * 获取列表展示数据
     * 
     * @param modelMap
     * @param sysDepartment
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysDepartment:select")
    @RequestMapping(value = "/list/all", method = RequestMethod.POST)
    @ResponseBody
    public Object findAll(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap,
            SysDepartment sysDepartment) throws Exception {
        List<SysDepartment> sysDepartmentList = sysDepartmentService.findAll(sysDepartment);
        return sysDepartmentList;
    }

    /**
     * 获取模块TREE页面JSON数据
     * 
     * @return
     * @throws Exception
     */
    @RequiresUser
    @RequestMapping(value = "/tree", method = RequestMethod.POST)
    @ResponseBody
    public Object tree() throws Exception {
        List<SysDepartment> mList = sysDepartmentService.findAll(null);
        List<TreeJson> tList = new ArrayList<TreeJson>();
        for (int i = 0; i < mList.size(); i++) {
            TreeJson tj = new TreeJson();
            tj.setId(mList.get(i).getId());
            tj.setPid(mList.get(i).getParentId());
            tj.setText(mList.get(i).getName());
            tList.add(tj);
        }
        TreeJson root = new TreeJson();
        root.setId(StringConstant.ROOT_ID_32);
        root.setText("系统部门");
        TreeJson.getTree(tList, root);
        JSONArray jsonObj = JSONArray.fromObject(root);
        return jsonObj;
    }

    /**
     * 保存新增的数据
     * 
     * @param modelMap
     * @param sysDepartment
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysDepartment:insert")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ResponseBody
    public String save(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysDepartment sysDepartment)
            throws Exception {
        if (!beanValidator(modelMap, sysDepartment)) {
            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
            return null;
        }
        sysDepartmentService.save(sysDepartment);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 保存修改的数据
     * 
     * @param modelMap
     * @param sysDepartment
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysDepartment:update")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public String update(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysDepartment sysDepartment)
            throws Exception {
        if (!beanValidator(modelMap, sysDepartment)) {
            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
            return null;
        }
        sysDepartmentService.update(sysDepartment);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 删除数据库
     * 
     * @param modelMap
     * @param sysDepartmentId
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysDepartment:delete")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public String delete(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, String id)
            throws Exception {
        List<String> listId = Arrays.asList(id.split(","));
        sysDepartmentService.delete(listId);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 用户信息模版导入
     * 
     * @param session
     * @param response
     * @param request
     * @throws Exception
     */
    @RequiresPermissions("sysDepartment:insert")
    @RequestMapping(value = "/templateImport", method = RequestMethod.POST)
    @ResponseBody
    public String templateImport(@RequestParam(value = "file", required = false) MultipartFile file, HttpSession session,
            HttpServletResponse response, HttpServletRequest request, ModelMap modelMap) {
        List<Row> rowList = new ArrayList<Row>();// 定义行对象
        try {
            rowList = ExcelUtil.getRows(file, 1);
        } catch (Exception e) {
            modelMap.put("message", "解析模版出错");
            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
            return null;
        }
        int dateNum = rowList.size();// 定义数据总条数
        int addNum = 0;// 定义新增数据条数
        int updateNum = 0;// 定义修改数据条数
        for (int i = 0; i < rowList.size(); i++) {
            Row row = rowList.get(i);
            /**
             * 获取所有列的值
             */
            String name = ExcelUtil.getStringCellValue(row.getCell(0));// 获取部门名称
            String code = ExcelUtil.getStringCellValue(row.getCell(1));// 获取部门编号
            String sequence = ExcelUtil.getStringCellValue(row.getCell(2));// 获取排序号
            String superiorDepartmentName = ExcelUtil.getStringCellValue(row.getCell(3));// 获取上机部门
            String superiorDepartmentId = null;// 上级部门名称赋值给superiorDepartmentName
            /**
             * 非空校验
             */
            if (StringUtils.isEmpty(name)) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门名称为空");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (StringUtils.isEmpty(code)) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门编号为空");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (StringUtils.isEmpty(sequence)) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的排序号为空");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (StringUtils.isEmpty(superiorDepartmentName)) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的上级部门为空");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }

            /**
             * 判断上级部门非空之后解析所在部门
             */
            String[] departments = superiorDepartmentName.split("/");
            if (departments.length >= 2) {// 判断数组中是否有多个部门
                /*
                 * 循环查询部门是否存在
                 */
                for (int j = 0; j < departments.length; j++) {
                    String deptName = departments[j];
                    // 判断第一次进来时当前节点是不是根节点
                    if (j == 0) {
                        SysDepartment sysDepartMent = sysDepartmentService.queryRoot(deptName);
                        if (null == sysDepartMent) {// 如果不是根节点，必须从根节点写起
                            modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门名称不存在，请确认组织节点是否正确。");
                            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                            return null;
                        }
                    }
                    String nextDeptName = null;
                    if (j < departments.length - 1) {
                        nextDeptName = departments[j + 1];
                    }
                    if (!StringUtils.isEmpty(nextDeptName)) {// 如果下级节点还有部门的话，则根据上级查询下级是否存在
                        SysDepartment sysDepartment = sysDepartmentService.queryLowerIsExistence(deptName, nextDeptName);
                        if (null == sysDepartment) { // 如果下级部门不存在，则说明该机构节点名称有误
                            modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门名称不存在，请确认组织节点是否正确。");
                            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                            return null;
                        }
                    } else {// 如果下级节点没有部门，该部门会当作上级部门。
                        List<SysDepartment> departmentList = sysDepartmentService.findByName(deptName);
                        SysDepartment sysDepartment = departmentList.get(0);
                        superiorDepartmentId = sysDepartment.getId();// 上级部门ID
                    }
                }
            }
            superiorDepartmentName = departments[departments.length - 1];
            /**
             * 长度校验
             */
            if (name.length() > 100) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门名称长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (code.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门编号长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (sequence.length() > 10) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的排序号长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (superiorDepartmentId.length() > 32) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的上级编码长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }

            // 绑定实体对象
            SysDepartment sysDepartment = new SysDepartment();
            sysDepartment.setName(name);
            sysDepartment.setCode(code);
            try {
                sysDepartment.setSequence(Long.parseLong(sequence));
            } catch (NumberFormatException e1) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的排序号格式有误，请输入数字。");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            sysDepartment.setParentId(superiorDepartmentId);
            // 保存部门
            SysDepartment department = sysDepartmentService.queryLowerIsExistence(superiorDepartmentName, name);// 根据上级部门名称和部门名称查询部门是否存在，存在做更新操作
            if (null != department) {// 如果部门不为空则表示更新
                sysDepartment.setId(department.getId());
                sysDepartmentService.update(sysDepartment);
                updateNum++;
            } else {// 否则执行新增操作
                sysDepartmentService.save(sysDepartment);
                addNum++;
            }
        }
        modelMap.put("message", "新增数据：" + addNum + "条，修改数据：" + updateNum + "条，失败：" + (dateNum - addNum - updateNum) + "条");
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

}